package com.concurrent.aqslock.part8.reent;

import java.util.concurrent.locks.ReentrantLock;

/**
 * 使用显示锁的范式
 */
public class LockDemo {
    private static ReentrantLock lock = new ReentrantLock();

    /**
     * 使用ReentrantLock锁
     */
    static class ReenTrantThread implements Runnable {
        private int count = 0;

        @Override
        public void run() {
            cyclic();
        }

        private void cyclic() {
            lock.lock();
            try {
                while (count < 2) {
                    System.out.println(Thread.currentThread().getName() + " count value: " + count);
                    Thread.sleep(1000);
                    ++count;
                    System.out.printf("Lock is get by CurrentThread: %s %s \n", Thread.currentThread().getName(), lock.isHeldByCurrentThread());
                    cyclic();
                    Thread.sleep(3000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                if (count >= 2 && lock.isHeldByCurrentThread()) {
                    System.out.printf("%s unlock ,queue length: %s \n",Thread.currentThread().getName(),lock.getQueueLength());
                    lock.unlock();
                }
            }
        }
    }

    /**
     * 使用synchronized锁
     */
    static class SysThread implements Runnable {
        private int count = 0;

        @Override
        public void run() {
            cyclic();
        }

        private synchronized void cyclic() {
            while (count < 2) {
                System.out.println(Thread.currentThread().getName() + " count value: " + count);
                ++count;
                cyclic();
            }
        }
    }

    public static void main(String[] arg0) throws InterruptedException {
        for (int i = 0; i < 2; ++i) {
            new Thread(new ReenTrantThread(), "ReenTrantThread " + i).start();
        }

        for (int i = 0; i < 2; ++i) {
            new Thread(new SysThread(), "SysThread " + i).start();
        }

        Thread.sleep(3000);
    }

}
